package cn.mw.cmdb.processor;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.mw.cmdb.entity.InstanceGroupByPathAndStatus;
import cn.mw.cmdb.entity.ModelGroupInfo;
import cn.mw.cmdb.entity.ModelInfo;
import cn.mw.cmdb.param.GroupSearchParam;
import cn.mw.cmdb.param.InstanceSearchParam;
import cn.mw.cmdb.param.ModelSearchParam;
import cn.mw.cmdb.service.impl.CmdbServiceManage;
import cn.mw.cmdb.service.impl.CustomModelServiceImpl;
import cn.mw.cmdb.service.impl.InstanceServiceImpl;
import cn.mw.cmdb.service.impl.ModelGroupServiceImpl;
import cn.mw.cmdb.util.AssetsTool;
import cn.mw.cmdb.util.CMDBTool;
import cn.mw.components.mongodb.entity.CriteriaOpsType;
import cn.mw.components.mongodb.entity.SubCondition;
import cn.mw.microMonitorCommon.api.cmdb.TreeView;
import cn.mw.microMonitorCommon.util.SpringUtils;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

import static cn.mw.cmdb.util.AssetsTool.ItemAssetsStatusContext;
import static cn.mw.cmdb.util.ValConvertUtil.strValueConvert;

@Slf4j
public class TreeProcessorAssetType implements TreeProccessorTable {
    private CmdbServiceManage cmdbServiceManage;

    public TreeProcessorAssetType(CmdbServiceManage cmdbServiceManage) {
        this.cmdbServiceManage = cmdbServiceManage;
    }

    @Override
    public List genTreeData(TableDataProcessorContext context) throws Exception {

        List<TreeView> ret = new ArrayList<>();
        InstanceServiceImpl instanceService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        long step1 = System.currentTimeMillis();
        InstanceSearchParam param = new InstanceSearchParam();
        BeanUtil.copyProperties(context.getTableSearchParam(), param, CopyOptions.create().setIgnoreNullValue(true));
        List<InstanceGroupByPathAndStatus> groupRet = instanceService.groupCountByPathAndStatus(param);

        Set<String> modelIds = new HashSet<>();
        Set<String> groupSet = new HashSet<>();
        Map<String, List<ItemAssetsStatusContext>> idContextMap = AssetsTool.initModelAndGroupIdSet(modelIds, groupSet, groupRet);

        long step2 = System.currentTimeMillis();
        log.info("instance cost {} ms", step2 - step1);
        CustomModelServiceImpl modelService = (CustomModelServiceImpl) cmdbServiceManage.getModelService(CustomModelServiceImpl.ID);
        ModelSearchParam searchParam = new ModelSearchParam();
        SubCondition subCondition = new SubCondition(CriteriaOpsType.in.name(), modelIds.stream().toList());
        searchParam.addSubCondition(CMDBTool.getFieldName(ModelInfo::getId), subCondition);
        List<ModelInfo> modelInfos = modelService.selectList(searchParam);
        if (null != modelInfos) {
            ret.addAll(modelInfos);
        }
        long step3 = System.currentTimeMillis();
        log.info("model cost {} ms", step3 - step2);
        //中间件Id
        String middlewareGroupId = SpringUtils.getPropertiesValue("base.middleware.groupId");
        String webMonitorGroupId = SpringUtils.getPropertiesValue("base.webMonitor.groupId");
        //判断是否中间件或者web监测菜单请求
        if (context.getTableSearchParam() != null && context.getTableSearchParam().getCondition() != null && context.getTableSearchParam().getCondition().get("path") != null) {
            String path = strValueConvert(context.getTableSearchParam().getCondition().get("path").getValue());
            if (!Strings.isNullOrEmpty(path) && (middlewareGroupId.equals(path) || webMonitorGroupId.equals(path))) {
                groupSet = new HashSet<>();
                groupSet.add(path);
            }
        }
        ModelGroupServiceImpl groupService = (ModelGroupServiceImpl) cmdbServiceManage.getModelService(ModelGroupServiceImpl.ID);
        GroupSearchParam groupSearchParam = new GroupSearchParam();
        subCondition = new SubCondition(CriteriaOpsType.in.name(), groupSet.stream().toList());
        groupSearchParam.addSubCondition(CMDBTool.getFieldName(ModelGroupInfo::getId), subCondition);
        List<ModelGroupInfo> groupInfos = groupService.doSelectList(groupSearchParam);
        //中间件菜单的树结构，中间件去掉path，直接成为父节点---新增web监测菜单也需要去掉path
        if (CollectionUtils.isNotEmpty(groupInfos) && groupInfos.size() == 1) {
            ModelGroupInfo groupInfo = groupInfos.get(0);
            if (middlewareGroupId.equals(groupInfo.getId()) || webMonitorGroupId.equals(groupInfo.getId())) {
                groupInfo.setPath(null);
            }
        }
        if (null != groupInfos) {
            ret.addAll(groupInfos);
        }
        long step4 = System.currentTimeMillis();
        log.info("group cost {} ms", step4 - step3);
        for (TreeView treeView : ret) {
            String id = strValueConvert(treeView.getId());
            List<ItemAssetsStatusContext> contexts = idContextMap.get(id);
            if (null != contexts) {
                treeView.setCount(AssetsTool.calcItemAssetsStatusCount(contexts));
                treeView.setItemAssetsStatus(AssetsTool.calcItemAssetsStatusContext(contexts, treeView));
            }
        }
        long step5 = System.currentTimeMillis();
        log.info("final cost {} ms", step5 - step4);
        return ret;
    }
}
